package com.saber.concurrentHashMap;

import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.saber.accumulator.AccumulateTypeConfig;
import com.saber.accumulator.ReportItemAccumulatorAdapter;
import com.saber.bean.Report;
import com.saber.bean.ReportItem;
import com.saber.bean.ReportItemQueue;

public class ConcurrentHashMapUtil {

	private static ConcurrentHashMap<String, ReportItemQueue> queueMap = new ConcurrentHashMap<String, ReportItemQueue>();

	private static final Logger logger = LoggerFactory.getLogger(ConcurrentHashMapUtil.class);

	private static ReportItemAccumulatorAdapter accumulator = new ReportItemAccumulatorAdapter();

	private static AccumulateTypeConfig accumulateTypeConfig = new AccumulateTypeConfig();

	/**
	 * @param report
	 * @param key
	 * @param value
	 * @param source
	 */
	private static void queueReportItem(Report report, String key, Object value, String source) {

		ReportItem ri = new ReportItem();
		ri.setReport(report);
		ri.setKey(key);
		ri.setValue(value.toString());
		ri.setSource(source);
		ri.setType(accumulateTypeConfig.getType(Report.ReportName.SERVICE_CONNECTION_CLIENT_IP_WINDOW_REPORT.name(), key));

		String ckey = key4ReportItem(report.getId(), key);
		final ReportItemQueue riMap = new ReportItemQueue(ri, (Integer)value);
		final Integer calVal = (Integer)value;

		if (!queueMap.containsKey(ckey)) {
			ReportItemQueue riMapNew = queueMap.putIfAbsent(ckey, riMap);
			if (null != riMapNew) {
				queueMap.compute(ckey, (k, rq) -> {
					if (rq == null) {
					// 如果该Key对应数据已被删除时，新增对应数据
					return riMapNew;
					} else {
						// 已经有记录ReportItem数据时，计算并存入该ReportItem信息
						// 根据不同计算规则计算大小
						accumulator.accumulate(null, rq.getRi(), calVal);
						rq.setResult(Integer.valueOf(rq.getRi().getValue()));
						return rq;
					}});
			}
		} else {
			queueMap.compute(ckey, (k, rq) -> {
				if (rq == null) {
					// 如果该Key对应数据已被删除时，新增对应数据
					return riMap;
				} else {
					// 已经有记录ReportItem数据时，计算并存入该ReportItem信息
					// 根据不同计算规则计算大小
					accumulator.accumulate(null, rq.getRi(), calVal);
					rq.setResult(Integer.valueOf(rq.getRi().getValue()));
					rq.getRi().setSource(source);
					return rq;
				}
			});
		}
		//logger.info(riMap.getRi().getSource() + ":" + riMap.getResult());
	}

	/**
	 * @param key
	 */
	private static void printQueue(String key) {
		ReportItemQueue rq = queueMap.get(key);
		logger.info(rq.getRi().getSource() + ":" + rq.getResult());
	}

	/**
	 * @param key
	 */
	public static void printQueueAll() {
		queueMap.forEach((key, rq)->{logger.info(rq.getRi().getSource() + ":" + rq.getResult());});
	}

	/**
	 * @param report
	 * @param key
	 * @param value
	 * @param source
	 */
	public static void analyzerReportItem(Report report, String key, Object value, String source) {
		String ckey = key4ReportItem(report.getId(), key);
		queueReportItem(report,key,value,source);
		printQueue(ckey);
	}

	/**
	 *
	 * @param report
	 * @param key
	 * @return
	 */
	private static String key4ReportItem(Long report, String key) {
		return "ri:" + report + "-" + key;
	}
}
